package com.gitee.taotaojs.generator;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.FileOutConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.gitee.taotaojs.mybootsuper.bean.BaseBean;
import com.gitee.taotaojs.mybootsuper.controller.MyComController;
import com.gitee.taotaojs.mybootsuper.mapper.MyComMapper;
import com.gitee.taotaojs.mybootsuper.service.IMyComService;
import com.gitee.taotaojs.mybootsuper.service.MyComService;
import com.gitee.taotaojs.table.MySqlConnection;
import com.gitee.taotaojs.util.ConstantUtil;
import com.gitee.taotaojs.util.StringUtil;
import com.gitee.taotaojs.util.reflect.MethodUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

/**
 * @author TaoTaojs
 * @date 2020/7/13 2:30 PM
 * <p>Description</p>
 * <h2>功能描述</h2>
 * 基于tkMapper自动生成代码的工具类
 * <h3>主要功能：</h3>
 * <ol>
 *     <li>基于tkMapper自动生成代码的工具类</li>
 * </ol>
 * <h3>关联类</h3>
 * <p>参考链接：</p>
 * <h2>更新日志</h2>
 * <p>[author]        [time]                      [version]          [desc]</p>
 * <p>TaoTaojs        2020/7/13 2:30 PM                V1.0          基于tkMapper自动生成代码的工具类</p>
 */
public class CodeGenerator {

    /** java路径 */
    private static final String JAVA_DIR = "/src/main/java";
    /** 资源路径 */
    private static final String RESOURCES_DIR = "/src/main/resources";

    /**
     * 读取控制台内容
     * @param tip 提示语（输入的字符串）
     * @return 输入的值
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入" + tip + "：");
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtil.isNotEmpty(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "！");
    }

    /**
     * 下划线命名转为驼峰命名
     * @param para 下划线命名的字符串
     * @param prefix 前缀，一般为tb_
     * @return 驼峰命名字符串
     */
    public static String underlineToHump(String para, String prefix) {
        para = para.replaceAll(prefix, "");
        StringBuilder result = new StringBuilder();
        String[] a = para.split("_");
        for (String s : a) {
            if (result.length() == 0) {
                result.append(s.toLowerCase());
            } else {
                result.append(s.substring(0, 1).toUpperCase());
                result.append(s.substring(1).toLowerCase());
            }
        }
        return result.toString();
    }

    /**
     * 自动生成代码的主要方法
     * @param tableName 表名称
     * @param generatorBean 生成代码的相关配置
     * @param fileOverride 是否覆盖原来代码
     */
    public static void generator(String tableName, GeneratorBean generatorBean, boolean fileOverride){

        List<String> tableNameList = MySqlConnection.getTableNames(tableName, generatorBean.getDataSourceConfig());
        String[] tableNames = tableNameList.toArray(new String[0]);
        //全局配置
        GlobalConfig gc = new GlobalConfig();
        gc.setActiveRecord(false)
                .setAuthor("TaoTaojs")
                .setOutputDir(generatorBean.getAbsolutePath() + JAVA_DIR)
                .setOpen(false)
                .setSwagger2(true)
                //关联数据库中日期类型为java包下的日期类型
                .setDateType(DateType.ONLY_DATE)
                .setEntityName("%sModel")
                .setMapperName("%sMapper")
//                .setXmlName("%sMapper")
                .setServiceName("I%sService")
                .setServiceImplName("%sServiceImpl")
                .setControllerName("%sController")
                .setBaseResultMap(true)
                .setBaseColumnList(true)
                .setFileOverride(fileOverride);

        //策略配置
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setCapitalMode(true)
//                .setDbColumnUnderline(true)
                .setNaming(NamingStrategy.underline_to_camel)
                .setColumnNaming(NamingStrategy.underline_to_camel)
                .setTablePrefix("tb_")
                .setControllerMappingHyphenStyle(true)
                .setCapitalMode(false)
                .setSuperEntityClass(BaseBean.class)
                .setSuperMapperClass(MyComMapper.class.getName())
                .setSuperControllerClass(MyComController.class)
                .setSuperServiceClass(IMyComService.class)
                .setSuperServiceImplClass(MyComService.class)
                .setEntityLombokModel(true)
                .setEntityBuilderModel(true)
                .setRestControllerStyle(true)
                .setInclude(tableNames);

        //包名策略配置
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent(generatorBean.getPackageName())
                .setModuleName(generatorBean.getModelName())
                .setEntity("pojo.model")
                .setService("service")
                .setServiceImpl("service.impl")
                .setController("controller")
                .setMapper("mapper");

        //模板配置
        TemplateConfig tc = new TemplateConfig();
        // 配置自定义输出模板
        //指定自定义模板路径，注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
        tc.setController("template_plus/controller.java")
                .setService("template_plus/service.java")
                .setServiceImpl("template_plus/serviceImpl.java")
                .setEntity("template_plus/entity.java")
                .setMapper("template_plus/mapper.java")
                .setXml(null);

        //自定义属性
        Map<String, Object> map = new HashMap<>(ConstantUtil.ONE);
        String templatePath = "/template_plus/mapper.xml.vm";
        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定义配置会被优先输出
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                map.put("RequestMappingName", MethodUtil.capitalizeDown(tableInfo.getEntityName().replace("Model", "")));
                // 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
                return generatorBean.getAbsolutePath() + RESOURCES_DIR + "/mapper/" + tableInfo.getEntityName().replace("Model", "") + "Mapper.xml";
            }
        });
        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                this.setMap(map);
            }
        };
        cfg.setFileOutConfigList(focList);

        //整合配置
        AutoGenerator ag = new AutoGenerator();
        ag.setGlobalConfig(gc)
                .setDataSource(generatorBean.getDataSourceConfig())
                .setStrategy(strategyConfig)
                .setPackageInfo(packageConfig)
                .setTemplate(tc)
                .setCfg(cfg);

        //执行
        ag.execute();
    }

    /**
     * 运行测试
     * @param args 参数
     */
    public static void main(String[] args) {
        DataSourceConfig dataSourceConfig  = new DataSourceConfig();

        GeneratorBean generatorNorm = GeneratorBean.builder()
                .absolutePath("/Users/work/WorkspacesIDEA/ronghanyiguan/thinkdid-hospital2.0/shxd-service/shxd-service-norm")
                .packageName("com.shxd.service")
                .modelName("norm")
                .dataSourceConfig(
                        dataSourceConfig.setDbType(DbType.MYSQL)
                                .setDriverName("com.mysql.cj.jdbc.Driver")
                                .setUrl("jdbc:mysql://localhost:3306/hospital2.0" +
                                        "?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false")
                                .setUsername("root")
                                .setPassword("123456"))
                .build();
        generator(
                "tb_norm",
                generatorNorm, false);

        int i = 1;
        if(1 == i) {
            return;
        }

        generator("tb_norm_item", GeneratorBean.builder()
                .absolutePath(System.getProperty("user.dir") + "/myboot-generator")
                .packageName("com.shxd.service.norm")
                .modelName("tb_norm_item")
                .build(), false);
    }

}
